package sharemem

import (
	"log"
	"server_cluster/battle/battle_config"
	"server_cluster/common/tools"
)

const (
	SKILL_TYPE_FREE			=	1
	SKILL_TYPE_STOP			=	2
	SKILL_TYPE_ALL_STOP		=	3
	SKILL_TYPE_ARMOR		=	4

	CARD_TAG_ATTACK			=	1
	CARD_TAG_SKILL			=	2
	CARD_TAG_EX_SKILL		=	3
)

//打断当前运行的技能 flag 是否打断普攻
func (target *Battle_unit)KillSkill(flag bool) {
	if target.run_card == nil {
		return
	}
	if !flag && target.run_card.tag == 1 {
		return
	}
	if target.run_card.child[target.run_card.index].Type == SKILL_TYPE_ARMOR{
		return
	}
	//打断前清除受击状态
	max := int8(len(target.run_card.child))
	for ;target.run_card.index < max;target.run_card.index++{
		for _,v1 :=range target.run_card.child[target.run_card.index].effect {
			for _,v2 := range v1.target {
				v2.SetState(TARGET,-1)
			}
		}
	}
	//
	target.run_card = nil
	target.PassiveStart(target,POS_ME_SKILL_KILL)
}

//是否命中弱点
func (target *Battle_unit)IsHitWeakPoint(dmg_type int8) bool {
	for _,v := range target.weak {
		if v == dmg_type {
			return true
		}
	}
	return false
}

//生成技能效果
func (c *Cfg_skill_effect)BuildSkillEffect(trigger *Battle_unit,target *Battle_unit) *Skill_effect {
	tmp := trigger.area.GetEffectTarget(c.target,trigger,target)
	if len(tmp) <= 0 {
		return nil
	}
	effect := &Skill_effect{
		trigger:trigger,
		target:nil,
		begin_time:c.begin_time,
		end_time:c.end_time,
		tag:c.tag,
		params:c.params,
	}
	for _,v := range tmp {
		if trigger.area.CheckConditions(c.ctype,c.condition,trigger,v) {
			effect.target = append(effect.target,v)
			//进入受击状态
			v.SetState(TARGET,1)
			//log.Printf("!!!!!!!!!!!!!!!Type %d take state target = %v begin_time=%v end_time=%v",v.Type,v.GetStateMap()[TARGET],effect.begin_time,effect.end_time)
		}
	}
	if len(effect.target) <= 0 {
		return nil
	}
	return effect
}
//获取伤害值
func (target *Battle_unit)GetSkillDmgValue(is_ex bool,trigger *Battle_unit,p1 []int32,p2 map[int32]int32,p3 int32,p6 int32,is_hit bool) (int32,bool) {
	if len(p1) != 3 {
		log.Printf("GetSkillDmgValue config BattleSkillEffect Param1 type-1 error.(%v)",p1)
		return 0,false
	}
	//所有临时属性生效
	attrinc := float32(0)		//某属性增伤
	attrpen := float32(0)		//某属性穿透
	attrres := float32(0)		//某属性抗性
	switch p3 {
		case 1:
			//火
			attrinc = float32(trigger.TakeAtVal(VAL_MAX,FIREINC) + p2[FIREINC])
			attrpen = float32(trigger.TakeAtVal(VAL_MAX,FIREPEN) + p2[FIREPEN])
			attrres = float32(target.TakeAtVal(VAL_MAX,FIRERES))
		case 2:
			//冰
			attrinc = float32(trigger.TakeAtVal(VAL_MAX,ICEINC) + p2[ICEINC])
			attrpen = float32(trigger.TakeAtVal(VAL_MAX,ICEPEN) + p2[ICEPEN])
			attrres = float32(target.TakeAtVal(VAL_MAX,ICERES))
		case 3:
			//风
			attrinc = float32(trigger.TakeAtVal(VAL_MAX,WINDINC) + p2[WINDINC])
			attrpen = float32(trigger.TakeAtVal(VAL_MAX,WINDPEN) + p2[WINDPEN])
			attrres = float32(target.TakeAtVal(VAL_MAX,WINDRES))
		case 4:
			//暗
			attrinc = float32(trigger.TakeAtVal(VAL_MAX,DARKINC) + p2[DARKINC])
			attrpen = float32(trigger.TakeAtVal(VAL_MAX,DARKPEN) + p2[DARKPEN])
			attrres = float32(target.TakeAtVal(VAL_MAX,DARKRES))
		case 5:
			//光
			attrinc = float32(trigger.TakeAtVal(VAL_MAX,LIGHTINC) + p2[LIGHTINC])
			attrpen = float32(trigger.TakeAtVal(VAL_MAX,LIGHTPEN) + p2[LIGHTPEN])
			attrres = float32(target.TakeAtVal(VAL_MAX,LIGHTRES))
		case 10:
			//劈砍
			attrinc = float32(trigger.TakeAtVal(VAL_MAX,CHOPINC) + p2[CHOPINC])
			attrpen = float32(trigger.TakeAtVal(VAL_MAX,CHOPPEN) + p2[CHOPPEN])
			attrres = float32(target.TakeAtVal(VAL_MAX,CHOPRES))
		case 11:
			//穿刺
			attrinc = float32(trigger.TakeAtVal(VAL_MAX,PUNCTINC) + p2[PUNCTINC])
			attrpen = float32(trigger.TakeAtVal(VAL_MAX,PUNCTPEN) + p2[PUNCTPEN])
			attrres = float32(target.TakeAtVal(VAL_MAX,PUNCTRES))
		case 12:
			//钝击
			attrinc = float32(trigger.TakeAtVal(VAL_MAX,BLUDINC) + p2[BLUDINC])
			attrpen = float32(trigger.TakeAtVal(VAL_MAX,BLUDPEN) + p2[BLUDPEN])
			attrres = float32(target.TakeAtVal(VAL_MAX,BLUDRES))
		case 13:
			//流体
			attrinc = float32(trigger.TakeAtVal(VAL_MAX,FLUIDINC) + p2[FLUIDINC])
			attrpen = float32(trigger.TakeAtVal(VAL_MAX,FLUIDPEN) + p2[FLUIDPEN])
			attrres = float32(target.TakeAtVal(VAL_MAX,FLUIDRES))
	}
	crit := trigger.TakeAtVal(VAL_MAX,CRIT) + p2[CRIT]							//暴击率
	critdmg := float32(trigger.TakeAtVal(VAL_MAX,CRITDMG) + p2[CRITDMG])		//暴击伤害
	defpen := float32(trigger.TakeAtVal(VAL_MAX,DEFPEN) + p2[DEFPEN])			//防御穿透
	dmginc := float32(trigger.TakeAtVal(VAL_MAX,DMGINC) + p2[DMGINC])			//造成伤害

	//log.Printf("crit(%v) crit_dmg(%v) def_pen(%v) dmg_inc(%v) attr_inc(%v) attr_pen(%v) attr_res(%v)",crit,critdmg,defpen,dmginc,attrinc,attrpen,attrres)
	//基础值
	value := float32(0)
	switch p1[1] {
		case 1:
			value = float32(trigger.TakeAtVal(VAL_MAX,ATK) * p1[2]) / 10000
		case 2:
			value = float32(trigger.TakeAtVal(VAL_MAX,DEF) * p1[2]) / 10000
		case 3:
			value = float32(trigger.TakeAtVal(VAL_MAX,HP) * p1[2]) / 10000
		case 4:
			value = float32(target.TakeAtVal(VAL_MAX,ATK) * p1[2]) / 10000
		case 5:
			value = float32(target.TakeAtVal(VAL_MAX,DEF) * p1[2]) / 10000
		case 6:
			value = float32(target.TakeAtVal(VAL_MAX,HP) * p1[2]) / 10000
		case 7:
			value = float32(p1[2])
	}

	//log.Printf("value = %v",value)
	//元素属性增伤区
	value_attrinc := 1 + attrinc/10000
	//伤害结果增伤区
	weak_counter := float32(battle_config.COUNTER0)
	if is_hit {
		weak_counter = battle_config.COUNTER1
	}
	value_dmginc := 1 + (weak_counter+dmginc+float32(p6))/10000
	//增伤修正
	value *= value_attrinc * value_dmginc
	//log.Printf("value(%v) value_attrinc(%v) value_dmginc(%v) | weak_counter(%v) dmginc(%v) | attrinc(%v)",value,value_attrinc,value_dmginc,weak_counter,dmginc,attrinc)


	//受伤结果区
	value_dmgdec := 1 + float32(target.TakeAtVal(VAL_MAX,DMGDEC))/10000
	//元素属性抗性区
	value_attrres := 1 + (attrpen - attrres)/10000
	//受伤修正
	value *= value_dmgdec * value_attrres
	//log.Printf("value(%v) value_dmgdec(%v) value_attrres(%v) | attrpen(%v) attrres(%v) | attr_target.DMGDEC(%v)",value,value_dmgdec,value_attrres,attrpen,attrres,attr_target[DMGDEC][VAL])


	//防御常量
	value_def_const := battle_config.DEFENCECONSTANT + battle_config.DEFENCEFACTOR*float32(trigger.TakeAtVal(VAL_MAX,GEARSCORE))/10000
	//防御穿透量
	value_def_pen := 1 - defpen/10000
	//防御减伤率
	value_def_dec := value_def_pen * float32(target.TakeAtVal(VAL_MAX,DEF)) / (float32(target.TakeAtVal(VAL_MAX,DEF)) + value_def_const)
	//防御修正
	value *= (1 - value_def_dec)
	//log.Printf("value(%v) value_def_dec(%v) | value_def_pen(%v)  attr_target.DEF(%v)  value_def_const(%v) | defpen(%v) | attr_trigger.GEARSCORE(%v)",value,value_def_dec,value_def_pen,attr_target[DEF][VAL],value_def_const,defpen,attr_trigger[GEARSCORE][VAL])


	//暴击概率
	crit -= target.TakeAtVal(VAL_MAX,CRITRES)
	is_double := tools.GetResultByPro(crit)
	if is_double {
		//暴击修正
		value *= (1 + critdmg/10000)
	}
	//log.Printf("value(%v) critdmg(%v)",value,critdmg)

	//随机浮动修正

	value *= float32(tools.GetResultByRegion(battle_config.DMG_RANDOM_MIN,battle_config.DMG_RANDOM_MAX))/10000
	//log.Printf("dmg rand-value(%v)",value)

	return int32(value),is_double
}
//获取治疗值
func (target *Battle_unit)GetSkillCureValue(trigger *Battle_unit,p1 []int32,p2 map[int32]int32) int32 {
	if len(p1) != 3 {
		log.Printf("GetSkillCureValue config BattleSkillEffect Param1 type-2 error.(%v)",p1)
		return 0
	}
	//所有临时属性生效
	cureinc := float32(trigger.TakeAtVal(VAL_MAX,CUREINC) + p2[CUREINC])
	//log.Printf("cureinc(%v)",cureinc)
	//基础值
	value := float32(0)
	switch p1[1] {
		case 1:
			value = float32(trigger.TakeAtVal(VAL_MAX,ATK) * p1[2]) / 10000
		case 2:
			value = float32(trigger.TakeAtVal(VAL_MAX,DEF) * p1[2]) / 10000
		case 3:
			value = float32(trigger.TakeAtVal(VAL_MAX,HP) * p1[2]) / 10000
		case 4:
			value = float32(target.TakeAtVal(VAL_MAX,ATK) * p1[2]) / 10000
		case 5:
			value = float32(target.TakeAtVal(VAL_MAX,DEF) * p1[2]) / 10000
		case 6:
			value = float32(target.TakeAtVal(VAL_MAX,HP) * p1[2]) / 10000
	}
	log.Printf("value(%v)",value)
	//治疗量加成修正
	value *= (1 + (cureinc + float32(target.TakeAtVal(VAL_MAX,BECUREINC)))/10000)
	//log.Printf("value(%v) cureinc(%v) attr_target.BECUREINC(%v)",value,cureinc,attr_target[BECUREINC][VAL])

	//随机浮动修正
	value *= float32(tools.GetResultByRegion(battle_config.DMG_RANDOM_MIN,battle_config.DMG_RANDOM_MAX))/10000
	//log.Printf("cure rand-value(%v)",value)

	return int32(value)
}
//伤害效果
func (target *Battle_unit)DoSkillDmg(is_ex bool,trigger *Battle_unit,p1 []int32,p2 map[int32]int32,p3 int32,p4 int32,p5 int32,p6 []int32) {
	is_hit := target.IsHitWeakPoint(int8(p3))
	p6_value := int32(0)
	if p6 != nil {
		switch p6[0] {
			case 1:
				switch p6[1] {
					case 1:
						buff := trigger.GetBuffMap(int8(p6[2]))[p6[3]]
						if buff != nil {
							p6_value = int32(buff.level) * p6[4]
						}
					case 2:
						buff := target.GetBuffMap(int8(p6[2]))[p6[3]]
						if buff != nil {
							p6_value = int32(buff.level) * p6[4]
						}
				}
			case 2:
				switch p6[1] {
					case 1:
						if trigger.TakeState(int8(p6[2])) {
							p6_value = p6[3]
						}
					case 2:
						if target.TakeState(int8(p6[2])) {
							p6_value = p6[3]
						}
				}
		}
	}
	value,is_double := target.GetSkillDmgValue(is_ex,trigger,p1,p2,p3,p6_value,is_hit)
	log.Printf("Get skill dmg value = %d",value)
	if value > 0 {
		target.DoHP(-value)
	}
	if p4 > 0 && value > 0{
		//吸血
		trigger.DoHP(value*p4)
	}
	if is_hit && p5 > 0{
		//扣韧
		target.ChangeAttr(VAL,TOUGH,p5)
		trigger.PassiveStart(target,POS_ME_EFFECT_TOUGH)
	}
	if is_double {
		trigger.PassiveStart(target,POS_ME_EFFECT_DMG_DOUBLE)
	}
}
//治疗效果
func (target *Battle_unit)DoSkillCure(trigger *Battle_unit,p1 []int32,p2 map[int32]int32) {
	value := target.GetSkillCureValue(trigger,p1,p2)
	log.Printf("Get skill cure value = %d",value)
	if value > 0 {
		target.ChangeAttr(VAL,HP,value)
	}
}
//获取技能属性修改值
func (target *Battle_unit)GetSkillChangeAttr(p1 []int32) []int32 {
	var res []int32
	if len(p1) != 4 {
		log.Printf("config BattleSkillEffect Param1 type-3 error.(%v)",p1)
		return res
	}
	if p1[2] == HP_REAL || p1[2] == ANGER_REAL || p1[2] == TOUGH_REAL {
		log.Printf("skill change attr id=%d error.",p1[2])
		return res
	}
	value := int32(0)
	switch p1[1] {
		case 1:
			value = target.TakeAtVal(VAL_INIT,p1[2])*p1[3]/10000
		case 2:
			value = p1[3]
	}
	if value == 0 {
		log.Printf("change attr value = 0")
		return res
	}
	res = append(res,p1[2],value)
	return res
}
//添加buff
func (target *Battle_unit)SkillAddBuff(trigger *Battle_unit,p1 []int32) {
	if len(p1) < 3 {
		log.Printf("config BattleSkillEffect Param1 type-4 error.(%v)",p1)
		return
	}
	if p1[1] <= 0 {
		log.Printf("skill add buff level %d error.",p1[1])
		return
	}
	//随机buff
	var i int
	tmp_rand := make([]int32,0)
	for i=2;i<len(p1);i++ {
		if p1[i] > 0 {
			tmp_rand = append(tmp_rand,p1[i])
		}
	}
	//
	target.AddBuff(trigger,tmp_rand[tools.GetResultByRegion(0,len(tmp_rand))],int8(p1[1]))
}
//驱散buff
func (target *Battle_unit)SkillClearBuff(p1 []int32) {
	if len(p1) != 5 {
		log.Printf("config BattleSkillEffect Param1 type-5 error.(%v)",p1)
		return
	}
	target.ClearBuff(int8(p1[1]),int8(p1[2]),p1[3],int8(p1[4]))
}
//抽卡
func (target *Battle_unit)SkillDrawCard(p1 []int32) {
	if len(p1) != 2 {
		log.Printf("config BattleSkillEffect Param1 type-6 error.(%v)",p1)
		return
	}
	if target.Type != UNIT_TYPE_ROLE || p1[1] <= 0{
		return
	}
	num := int32(battle_config.CARD_NUM_MAX - target.area.card_num)
	if num <= 0 {
		return
	}
	if num > p1[1] {
		num = p1[1]
	}
	target.DrawCard(int(num))
}
//
func (target *Battle_unit)SkillResurrect(site int8) {
	log.Printf("开始复活单位 site %d",site)
	if target.Type != UNIT_TYPE_MONSTER {
		log.Printf("角色不能复活单位")
		return
	}
	if site < 0 || site >= BATTLE_MONSTER {
		log.Printf("复活位置 %d error.",site)
		return
	}
	area := target.area
	monster := area.GetUnit(UNIT_TYPE_MONSTER,site)
	log.Printf("monster exist=%v alive=%v",monster.Exist(),monster.Alive())
	if !monster.Exist() || monster.Alive(){
		log.Printf("不存在或未阵亡")
		return
	}

	user:=Get_user_by_index(area.shmUser_index)
	area.monster[site] = user.game_data.ft[area.fight_index].monster[site].Build(area)
	log.Printf("复活单位完成 site %d",site)
}

//
func (e *Skill_effect)DoEffect() {
	//log.Printf("e.target = %v",e.target)
	for _,target :=range e.target {
		for _,p1 :=range e.params.p1 {
			switch p1[0] {
				case 1:
					//伤害
					log.Printf("skill dmg")
					e.trigger.PassiveStart(target,POS_ME_EFFECT_DMG_BEGIN)
					target.DoSkillDmg(false,e.trigger,p1,e.params.p2,e.params.p3,e.params.p4,e.params.p5,e.params.p6)
					if !target.Alive() {
						e.trigger.PassiveStart(target,POS_ME_EFFECT_DMG_DEAD)
					}
					e.trigger.PassiveStart(target,POS_ME_EFFECT_DMG_END)
				case 2:
					//治疗
					log.Printf("skill cure")
					target.DoSkillCure(e.trigger,p1,e.params.p2)
					e.trigger.PassiveStart(target,POS_ME_EFFECT_CURE)
				case 3:
					//属性修改
					log.Printf("skill change attr")
					base := target.GetSkillChangeAttr(p1)
					if len(base) <= 0 {
						return
					}
					target.ChangeAttr(VAL_MAX,base[0],base[1])
				case 4:
					//添加增益buff
					target.SkillAddBuff(e.trigger,p1)
					var i int8
					if e.trigger.Type == UNIT_TYPE_MONSTER {
						for i=0;i<BATTLE_MONSTER;i++ {
							if !e.trigger.area.monster[i].Alive() {
								continue
							}
							e.trigger.area.monster[i].PassiveStart(target,POS_MY_EFFECT_BUFF_ADD)
						}
					} else {
						for i=0;i<BATTLE_ROLE;i++ {
							if !e.trigger.area.role[i].Alive() {
								continue
							}
							e.trigger.area.role[i].PassiveStart(target,POS_MY_EFFECT_BUFF_ADD)
						}
						for i=0;i<BATTLE_ROLE_ASSIST;i++ {
							if !e.trigger.area.role_assist[i].Alive() {
								continue
							}
							e.trigger.area.role_assist[i].PassiveStart(target,POS_MY_EFFECT_DEBUFF_ADD)
						}
					}
				case 5:
					//驱散buff
					log.Printf("skill clear buff")
					target.SkillClearBuff(p1)
					e.trigger.PassiveStart(target,POS_ME_EFFECT_BUFF_CLEAR)
				case 6:
					//抽卡
					log.Printf("skill draw card")
					target.SkillDrawCard(p1)
				case 7:
					//添加减益buff
					log.Printf("skill add debuff")
					target.SkillAddBuff(e.trigger,p1)
					var i int8
					if e.trigger.Type == UNIT_TYPE_MONSTER {
						for i=0;i<BATTLE_MONSTER;i++ {
							if !e.trigger.area.monster[i].Alive() {
								continue
							}
							e.trigger.area.monster[i].PassiveStart(target,POS_MY_EFFECT_DEBUFF_ADD)
						}
					} else {
						for i=0;i<BATTLE_ROLE;i++ {
							if !e.trigger.area.role[i].Alive() {
								continue
							}
							e.trigger.area.role[i].PassiveStart(target,POS_MY_EFFECT_DEBUFF_ADD)
						}
						for i=0;i<BATTLE_ROLE_ASSIST;i++ {
							if !e.trigger.area.role_assist[i].Alive() {
								continue
							}
							e.trigger.area.role_assist[i].PassiveStart(target,POS_MY_EFFECT_DEBUFF_ADD)
						}
					}
				case 8:
					//怒气充能
					log.Printf("skill add anger")
					rage := int32(0)
					switch p1[1] {
						case 1:
							rage = target.TakeAtVal(VAL_MAX,ANGER)*p1[2]/10000*target.TakeAtVal(VAL_MAX,CHARGE)/10000
						case 2:
							rage = p1[2] * target.TakeAtVal(VAL_MAX,CHARGE)/10000
					}
					target.ChangeAttr(VAL,ANGER,rage)
				case 9:
					//复活
					target.SkillResurrect(int8(p1[1])-1)
				case 10:
					//追击伤害
					log.Printf("skill dmg ex")
					target.DoSkillDmg(true,e.trigger,p1,e.params.p2,e.params.p3,e.params.p4,e.params.p5,e.params.p6)
					if !target.Alive() {
						e.trigger.PassiveStart(target,POS_ME_EFFECT_DMG_DEAD)
					}
				case 11:
					//附加冰冻值
					target.ChangeAttr(VAL,FREEZEVALUE,p1[1])
			}
		}
		switch e.tag {
			case 1:
				e.trigger.PassiveStart(target,POS_ME_EFFECT_TAG_1)
			case 2:
				e.trigger.PassiveStart(target,POS_ME_EFFECT_TAG_2)
				e.trigger.PassiveStart(target,POS_ME_EFFECT_TAG_23)
			case 3:
				e.trigger.PassiveStart(target,POS_ME_EFFECT_TAG_23)
			case 4:
				e.trigger.PassiveStart(target,POS_ME_EFFECT_TAG_4)
			case 5:
				if !target.Alive() {
					e.trigger.PassiveStart(target,POS_ME_EFFECT_TAG5_DEAD)
				}
		}
	}
}

//true 完成 false未完成
func (e *Skill_effect)CheckEffect(Type int8) bool {
	//log.Printf("check effect Type = %d,begin_time=%d root_time=%d node_time=%d",Type,e.begin_time,e.trigger.area.root_time,e.trigger.area.node_time)
	switch Type {
		case 2:
			if e.begin_time == -1 {
				//已生效
				if e.end_time <= e.trigger.area.node_time {
					//已完成
					for _,target := range e.target {
						//清除受击状态
						target.SetState(TARGET,-1)
						//log.Printf("@@@@@@@@@@@@@@@@Type %d take state target = %v ishealthy = %v hp=%d",target.Type,target.GetStateMap()[TARGET],target.IsHealthy(),target.TakeAtVal(VAL,HP))
						if !target.TakeState(TARGET) && !target.IsHealthy(){
							target.SetState(DEAD,1)
						}
					}
					return true
				}
			} else if e.begin_time <= e.trigger.area.node_time {
				//开始生效
				e.DoEffect()
				//
				e.begin_time = -1
				if e.end_time <= e.trigger.area.node_time {
					//已完成
					for _,target := range e.target {
						//清除受击状态
						target.SetState(TARGET,-1)
						//log.Printf("@@@@@@@@@@@@@@@@Type %d take state target = %v ishealthy = %v hp=%d",target.Type,target.GetStateMap()[TARGET],target.IsHealthy(),target.TakeAtVal(VAL,HP))
						if !target.TakeState(TARGET) && !target.IsHealthy(){
							target.SetState(DEAD,1)
						}
					}
					return true
				}
			}
		case 3:
			if e.begin_time == -1 {
				//已生效
				if e.end_time <= e.trigger.area.ex_time {
					//已完成
					for _,target := range e.target {
						//清除受击状态
						target.SetState(TARGET,-1)
						//log.Printf("@@@@@@@@@@@@@@@@Type %d take state target = %v ishealthy = %v hp=%d",target.Type,target.GetStateMap()[TARGET],target.IsHealthy(),target.TakeAtVal(VAL,HP))
						if !target.TakeState(TARGET) && !target.IsHealthy(){
							target.SetState(DEAD,1)
						}
					}
					return true
				}
			} else if e.begin_time <= e.trigger.area.ex_time {
				//开始生效
				e.DoEffect()
				//
				e.begin_time = -1
				if e.end_time <= e.trigger.area.ex_time {
					//已完成
					for _,target := range e.target {
						//清除受击状态
						target.SetState(TARGET,-1)
						//log.Printf("@@@@@@@@@@@@@@@@Type %d take state target = %v ishealthy = %v hp=%d",target.Type,target.GetStateMap()[TARGET],target.IsHealthy(),target.TakeAtVal(VAL,HP))
						if !target.TakeState(TARGET) && !target.IsHealthy(){
							target.SetState(DEAD,1)
						}
					}
					return true
				}
			}
		case 9:
			if e.begin_time == -1 {
				//已生效
				if e.end_time <= e.trigger.area.real_time {
					//已完成
					for _,target := range e.target {
						//清除受击状态
						target.SetState(TARGET,-1)
						//log.Printf("@@@@@@@@@@@@@@@@Type %d take state target = %v ishealthy = %v hp=%d",target.Type,target.GetStateMap()[TARGET],target.IsHealthy(),target.TakeAtVal(VAL,HP))
						if !target.TakeState(TARGET) && !target.IsHealthy(){
							target.SetState(DEAD,1)
						}
					}
					return true
				}
			} else if e.begin_time <= e.trigger.area.real_time {
				//开始生效
				e.DoEffect()
				//
				e.begin_time = -1
				if e.end_time <= e.trigger.area.real_time {
					//已完成
					for _,target := range e.target {
						//清除受击状态
						target.SetState(TARGET,-1)
						//log.Printf("@@@@@@@@@@@@@@@@Type %d take state target = %v ishealthy = %v hp=%d",target.Type,target.GetStateMap()[TARGET],target.IsHealthy(),target.TakeAtVal(VAL,HP))
						if !target.TakeState(TARGET) && !target.IsHealthy(){
							target.SetState(DEAD,1)
						}
					}
					return true
				}
			}
		default:
			if e.begin_time == -1 {
				//已生效
				if e.end_time <= e.trigger.area.root_time {
					//已完成
					for _,target := range e.target {
						//清除受击状态
						target.SetState(TARGET,-1)
						//log.Printf("@@@@@@@@@@@@@@@@Type %d take state target = %v ishealthy = %v hp=%d",target.Type,target.GetStateMap()[TARGET],target.IsHealthy(),target.TakeAtVal(VAL,HP))
						if !target.TakeState(TARGET) && !target.IsHealthy(){
							target.SetState(DEAD,1)
						}
					}
					return true
				}
			} else if e.begin_time <= e.trigger.area.root_time {
				//开始生效
				e.DoEffect()
				//
				e.begin_time = -1
				if e.end_time <= e.trigger.area.root_time {
					//已完成
					for _,target := range e.target {
						//清除受击状态
						target.SetState(TARGET,-1)
						//log.Printf("@@@@@@@@@@@@@@@@Type %d take state target = %v ishealthy = %v hp=%d",target.Type,target.GetStateMap()[TARGET],target.IsHealthy(),target.TakeAtVal(VAL,HP))
						if !target.TakeState(TARGET) && !target.IsHealthy(){
							target.SetState(DEAD,1)
						}
					}
					return true
				}
			}
	}
	return false
}

//true 全部完成 false未完成
func (c *Skill_child)CheckChild() bool {
	status := true
	for _,v := range c.effect {
		if !v.CheckEffect(c.Type) {
			//未完成
			status = false
		}
		//log.Printf("effect = %v,status = %v",v,status)
	}
	return status
}

func (c *Skill_child)SetTime() {
	for _,v :=range c.effect {
		switch c.Type {
			case 2:
				//半时停
				v.begin_time += v.trigger.area.node_time
				v.end_time += v.trigger.area.node_time
				v.trigger.area.SetEventMap(v.trigger.area.root_time,v.begin_time,0)
				v.trigger.area.SetEventMap(v.trigger.area.root_time,v.end_time,0)
			case 3:
				//全时停
				v.begin_time += v.trigger.area.ex_time
				v.end_time += v.trigger.area.ex_time
				v.trigger.area.SetEventMap(v.trigger.area.root_time,v.trigger.area.node_time,v.begin_time)
				v.trigger.area.SetEventMap(v.trigger.area.root_time,v.trigger.area.node_time,v.end_time)
			case 9:
				//真实时间
				v.begin_time += v.trigger.area.real_time
				v.end_time += v.trigger.area.real_time
				v.trigger.area.SetRealEventMap(v.begin_time)
				v.trigger.area.SetRealEventMap(v.end_time)
			default:
				//不时停
				v.begin_time += v.trigger.area.root_time
				v.end_time += v.trigger.area.root_time
				v.trigger.area.SetEventMap(v.begin_time,0,0)
				v.trigger.area.SetEventMap(v.end_time,0,0)
		}
	}
}

//true 全部完成 false未完成
func (u *Battle_unit)CheckSkill() {
	if u.run_card == nil {
		return
	}
	if !u.run_card.child[u.run_card.index].CheckChild() {
		//效果未完成
		return
	}
	u.run_card.index++
	if u.run_card.index < 0 || int(u.run_card.index) >= len(u.run_card.child) {
		u.run_card = nil
		return
	}
	u.run_card.child[u.run_card.index].SetTime()
	u.CheckSkill()
}

func (trigger *Battle_unit)UseSkill(target *Battle_unit,skill *Cfg_skill) bool {
	if trigger.run_card != nil {
		//有技能正在运行
		if trigger.run_card.end_time >= trigger.area.cd_time {
			log.Printf("run card is running.end_time=%d cd_time=%d",trigger.run_card.end_time,trigger.area.cd_time)
			return false
		}
		//打断技能
		trigger.KillSkill(true)
	}
	pool := &Skill_card_pool {
		tag:skill.tag,
		end_time:trigger.area.cd_time+skill.cd_time,
		index:0,
	}

	for _,v := range skill.skill_child {
		if v.Type == 2 && trigger.Type == UNIT_TYPE_MONSTER {
			log.Printf("monster %d can't use skill child type=2",trigger.id)
			continue
		}
		child := &Skill_child{
			Type:v.Type,
		}
		for _,v1 := range v.skill_effect {
			tmp_effect := v1.BuildSkillEffect(trigger,target)
			if tmp_effect == nil {
				continue
			}
			child.effect = append(child.effect,tmp_effect)
		}
		if len(child.effect) <= 0 {
			log.Printf("build skill effect nil.")
			continue
		}
		pool.child = append(pool.child,child)
	}
	if len(pool.child) <= 0 {
		log.Printf("build skill child nil.")
		return true
	}
	pool.child[pool.index].SetTime()
	trigger.run_card = pool
	//log.Printf("run_card= %v",trigger.run_card)
	//创建完成，直接运行一次
	trigger.CheckSkill()
	return true
}
//判断单位是否有卡牌限制状态
func (u *Battle_unit)SkillCheckState(card *Cfg_skill_card) bool {
	if u.IsControl() {
		return false
	}
	if card.tag != 1 && u.TakeState(SILENT){
		return false
	}
	return true
}

func (trigger *Battle_unit)UseSkillCard(target *Battle_unit,card *Cfg_skill_card,num int8) bool {
	//自身状态判断
	if !trigger.SkillCheckState(card) {
		log.Printf("skill check state false.")
		return false
	}
	if card.tag == 3 {
		//大招
		attr := trigger.GetAtMap()[ANGER]
		if attr==nil || !attr.IsFull() {
			log.Printf("rage is not full.")
			return false
		}
		//清空怒气
		trigger.ChangeAttr(VAL,ANGER,0)
	}
	//选择范围
	tmp := trigger.area.GetCardTarget(card.target,trigger,target)
	if tmp == nil {
		log.Printf("trigger %d=%d get card target nil.%v",trigger.Type,trigger.index,card.target)
		return true
	}

	switch num {
		case 1:
			if !trigger.UseSkill(tmp,card.skill1) {
				return false
			}
		case 2:
			if !trigger.UseSkill(tmp,card.skill2) {
				return false
			}
		case 3:
			if !trigger.UseSkill(tmp,card.skill3) {
				return false
			}
		default:
			return false
	}
	switch card.tag {
		case 2:
			trigger.PassiveStart(tmp,POS_ME_SKILL_2)
		case 3:
			trigger.PassiveStart(tmp,POS_ME_SKILL_23)
			trigger.PassiveStart(tmp,POS_ME_SKILL_3)
	}
	return true
}
//序列
func (trigger *Battle_unit)UseOrder() bool {
	log.Printf("序列攻击 Type %d index %d use order %v",trigger.Type,trigger.index,trigger.order[trigger.order_index].skill_card)
	return trigger.UseSkillCard(nil,trigger.order[trigger.order_index].skill_card,1)
}
//大招
func (trigger *Battle_unit)UseExCard(target *Battle_unit) bool {
	log.Printf("大招 Type %d index %d use exskill %v",trigger.Type,trigger.index,trigger.ex_card)
	return trigger.UseSkillCard(target,trigger.ex_card,1)
}
//使用卡牌
func (trigger *Battle_unit)UseCard(target *Battle_unit,card_id int32,num int8) bool {
	log.Printf("使用卡牌 Type %d index %d card %d - %d,[%v]",trigger.Type,trigger.index,card_id,num,trigger.GetDrawCardMap())
	//检查卡牌
	if card_id == trigger.ex_card.id {
		//大招
		return trigger.UseExCard(target)
	}
	if !trigger.CardEnough(card_id,num) {
		log.Printf("card enough error.")
		return false
	}
	cfg_card := trigger.GetNormalCardMap()[card_id]
	if cfg_card == nil {
		log.Printf("cfg card not found.")
		return false
	}

	if !trigger.UseSkillCard(target,cfg_card,num) {
		return false
	}
	//扣除卡牌
	trigger.ChangeCard(card_id,-num)
	trigger.area.card_num -= num
	return true
}
